﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Validity.Contexts;
using Validity.Rules;

namespace Validity.Test.Contexts
{
  [TestClass]
  public class ComparableValidationContextTest
  {
    private readonly StubValidationContext<IComparable> _context = new StubValidationContext<IComparable>();

    [TestMethod]
    public void TestDefaultCtor()
    {
      Assert.IsNotNull(new ComparableValidationContext<ObjectStub, IComparable>());
    }

    [TestMethod]
    public void TestWhenUsingIComparer()
    {
      Assert.IsNotNull(CreateConditionalValidationContext("A VALUE").WhenUsingComparer(StringComparer.OrdinalIgnoreCase));
      VerifyDecorateedRule(new ObjectStub(), "A value");
    }

    [TestMethod]
    public void TestWhenUsingComparisonDelegate()
    {
      Comparison<IComparable> comparer = (lhs, rhs) => String.Compare((String)lhs, (String)rhs, StringComparison.OrdinalIgnoreCase);

      Assert.IsNotNull(CreateConditionalValidationContext("A VALUE").WhenUsingComparer(comparer));
      VerifyDecorateedRule(new ObjectStub(), "A value");
    }
    
    private ComparableValidationContext<ObjectStub, IComparable> CreateConditionalValidationContext(String lhs)
    {
      var context = new ComparableValidationContext<ObjectStub, IComparable>(_context);
      var rule = new ComparisonRule<ObjectStub, IComparable>(value => lhs, result => result == 0, (obj, val) => "Original Message");

      _context.Rule.Add(rule);

      return context;
    }

    private void VerifyDecorateedRule(ObjectStub obj, IComparable value)
    {
      IRule<ObjectStub, IComparable> rule = _context.Rule[0];

      Assert.IsFalse(rule.IsViolatedBy(obj, value));
    }
  }
}
